home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / source / pam.asm < prev    next >
Encoding:
Assembly Source File  |  1991-08-31  |  10.5 KB  |  447 lines

  1.     page    132,63,1,1
  2.     opt    rc
  3.     title    'PAM Modulation/Demodulation'
  4.  
  5. ;***************************************************************
  6. ;* PAM.ASM -- PAM Modulation/Demodulation and               *
  7. ;*          SSI drivers                       *
  8. ;*                                   *
  9. ;* Provides interrupt based SSI handling, sample buffering     *
  10. ;* and PAM modulation and demodulation.                *
  11. ;*                                   *
  12. ;* PAM modulation and demodulation is based on some ideas      *
  13. ;* presented in book                           *
  14. ;*    Lee, E., A., Messerschmitt, D., G.:               *
  15. ;*    "Digital Communication",                   *
  16. ;*    Kluwer, 1988                           *
  17. ;*                                   *
  18. ;* Symbol syncronization is based on article               *
  19. ;*    Glisic, S., G.:                        *
  20. ;*    "Symbol Syncronization in Digital Communications       *
  21. ;*     Using Partial Response CPM signaling",                *
  22. ;*    IEEE Trans. on Comm., Vol. 37, No. 3, March 1989       *
  23. ;*                                   *
  24. ;* This module uses registers as follows:               *
  25. ;*  r0 - general purpose (temporary use)               *
  26. ;*  r2 - input sample write pointer                   *
  27. ;*  r3 - output sample read pointer                   *
  28. ;*  r4 - general purpose (temporary use)               *
  29. ;*  r6 - input sample read pointer                   *
  30. ;*  r7 - output sample write pointer                   *
  31. ;*                                   *
  32. ;* Copyright (C) 1991 by Alef Null. All rights reserved.       *
  33. ;* Author(s): Jarkko Vuori, OH2LNS                   *
  34. ;* Modification(s):                           *
  35. ;***************************************************************
  36.  
  37.     nolist
  38.     include 'ioequlc'
  39.     list
  40.  
  41.     section PAM
  42.     xdef    ssi_ini,modem_i
  43.     xdef    m_loop
  44.     xref    putbit,getbit
  45.     xref    m_cra,m_crb,m_tde,m_sr,m_tx
  46.  
  47.     org    p:
  48.  
  49.     nolist
  50.     include 'macros'
  51.     list
  52.  
  53. ; PAM parameters
  54. poly    equ $10800                    ; G3RUH,K9NG scrambler polynomial (x^17 + x^12 + 1)
  55. rfilt    equ     0.02                    ; random walk filter constant
  56. adjlen    equ    32                    ; ADC timing control lenght (in samples)
  57.  
  58. alpha    equ    1.0/(2.0*13.0)*0.5
  59. level    equ    0.05
  60. agcfilt equ    0.008
  61.  
  62. ; module status bits
  63. toggle    equ    6                    ; every other bit counter
  64.  
  65.  
  66. ;****************************
  67. ;*    SSI initialization    *
  68. ;****************************
  69. ssi_ini
  70. ; initialize SSI,
  71.     IF    !DEBUG
  72.     movep            #$4000,x:m_cra        ; 16 bit word
  73.     movep            #$f200,x:m_crb        ; syncronous,word frame,ext clk
  74.     ELSE
  75.     movep            #$4011,x:m_cra        ; 16 bit word, abt. 19.2 ksamples/s
  76.     movep            #$f620,x:m_crb        ; syncronous,word frame,ext clk
  77.     ENDIF
  78.  
  79.     rts
  80.  
  81.  
  82. ;****************************
  83. ;*      ADC & MODEM        *
  84. ;*    initialization        *
  85. ;****************************
  86. modem_i
  87. ; program the A/D & D/A converter chip (TLC32044, master clock is 5.184MHz)
  88. ; disable A/D high-pass filter, disable loopback, disable AUX IN,
  89. ; select syncronous mode, select input span 3Vpp, insert sinx/x correction
  90. ; lowpass cutoff frequency at    6840Hz -> TA  =  5 (SCF = 518.4kHz)
  91. ; sampling frequency is        19200Hz -> TB  = 27
  92. ; unit sampling correction time  0.4uS -> TA' =  2
  93.     pgmtlc    %10101000,5,2,27
  94.  
  95. ; sample handling,
  96.     move            #<insamp,r6
  97.     move            #<inN-N,n6
  98.     move            #<inN-1,m6
  99.     move            r6,r2
  100.     move            m6,m2
  101.     movi    0,x:<samque
  102.  
  103.     move            #<outsamp,r3
  104.     move            #<outN-1,m3
  105.     move            #<outsamp+1,r7
  106.     move            m3,m7
  107.     movi    <outfilt,x:<outfptr
  108.  
  109. ; ADC command word and initial AGC
  110.     movi    0,x:<adcnt
  111.     movi    1.0/64.0,x:<agcgain
  112.  
  113.     rts
  114.  
  115.  
  116. ;****************************
  117. ;*      Main Loop        *
  118. ;****************************
  119. loop    wait
  120. m_loop
  121.  
  122.  
  123. ;****************************
  124. ;*      Receiver        *
  125. ;****************************
  126. ; check if there are new samples received
  127. rec    move            r2,a
  128.     move            r6,x0
  129.     cmp    x0,a        #<rcos,r0
  130.     jeq    <xmit
  131.  
  132. ; yes, there indeed are new samples, check if receiver enabled
  133.     jset    #ptt,x:<status,xmit
  134.  
  135. ; remove any DC-level (with high-pass filter)
  136.     move            x:(r6),a
  137.     hpass    a,20.0/19200.0,rdc
  138.  
  139. ; AGC
  140.     move    a,x0
  141.     move            x:<agcgain,x1
  142.     mpy    x0,x1,a
  143.     rep    #6
  144.     asl    a
  145.     move            a,x:(r6)
  146.  
  147. ; fractional spaced equalizer (FSE) - filter part
  148.     conv    1,N,r6,r0,a
  149.  
  150. ; limit to binary and queue received bits
  151.     andi    #$fe,ccr
  152.     jmi    <ssi_r00
  153.     ori    #$01,ccr
  154. ssi_r00 move            x:<samque,b1
  155.     rol    b        (r6)+n6
  156.     move            b1,x:<samque
  157.  
  158. ; queue received samples
  159.     move            y:<dsample,b1
  160.     move            b1,y:<zsample
  161.     move            a,y:<dsample
  162.  
  163. ; check if one symbol (2 samples) received
  164.     bchg    #toggle,x:<status
  165.     jcc    <ssi_end
  166.  
  167. ; calculate the error
  168.     neg    a        #-level,x1            ; x1 = alpha*(desired-filtered)
  169.     jpl    <in1
  170.     move            #level,x1
  171. in1    add    x1,a        #alpha,x0
  172.     move    a,x1
  173.     mpyr    x0,x1,b     #<rcos,r0
  174.  
  175. ; calculate a new agc
  176.     move            y:<dsample,a        ; agcgain = (|desired|-|filtered|)*agcfilt+agcgain
  177.     abs    a        #level,x0
  178.     neg    a        #agcfilt,y1
  179.     add    x0,a        b,x1
  180.     move    a,y0
  181.     mpyr    y0,y1,a     x:<agcgain,x0
  182.     add    x0,a        #<rcos,r4
  183.     abs    a
  184.     move            a,x:<agcgain
  185.  
  186.     jclr    #dcd,x:<status,in2
  187. ; fractional Spaced Equalizer (FSE) - Adaptation part (LMS)
  188.     move            (r6)+            ; adjust to x(0)
  189.     move            x:(r6)+,x0    y:(r0)+,a   ; get x(0), c0
  190.     do    #N,incupd
  191.     macr    x0,x1,a     x:(r6)+,x0    y:(r0)+,y0  ; c = c + e(n) * x(n)
  192.     tfr    y0,a            a,y:(r4)+   ; copy c, save new c
  193. incupd
  194.     move            (r6)-            ; readjust sample pointer
  195.     move            (r6)-
  196.     move            (r6)+n6
  197. in2
  198.  
  199. ; check if carrier present
  200. ; by checking when eye is open
  201. ; (enought difference between zero crossing sample and decision sample)
  202.     move            y:<dsample,a        ; filter decision samples
  203.     abs    a
  204.     lpass    a,6.0/9600.0,rds
  205.  
  206.     move            y:<zsample,b        ; filter zero crossing samples
  207.     abs    b
  208.     lpass    b,6.0/9600.0,rzs
  209.  
  210.     sub    b,a        #level/7.0,x0        ; check their difference
  211.     jclr    #dcd,x:<status,lop
  212.     move            #level/1400.0,x0
  213.     cmp    x0,a
  214.     jlt    <doff
  215.     jmp    <ssi_r0a
  216. lop    cmp    x0,a
  217.     jge    <ssi_r0a
  218.  
  219. ; DCD off detected
  220. doff    bclr    #dcd,x:<status
  221.     jcc    <ssi_r0b
  222.     dcdoff
  223.     move            #>xcos,r0            ; reset input filter coeffs
  224.     move            #>rcos,r4
  225.     do    #N,_ecopy
  226.     move            y:(r0)+,a1
  227.     move            a1,y:(r4)+
  228. _ecopy
  229.     jsset    #req,x:<status,kickx            ; call persistence routine if needed
  230.     jmp    <ssi_r0b
  231.  
  232. ; DCD on detected
  233. ssi_r0a bset    #dcd,x:<status
  234.     jcs    <ssi_r0b
  235.     dcdon
  236.  
  237. ; check if there are transitions (by analyzing the sample between decision samples)
  238. ; and set a register appropriately
  239. ssi_r0b clr    a        #rfilt,x1
  240.     jclr    #0,x:<samque,ssi_r2
  241.     jset    #2,x:<samque,ssi_r3
  242. ; 0x1
  243.     move            y:<zsample,a
  244.     jmp    <ssi_r3
  245. ssi_r2    jclr    #2,x:<samque,ssi_r3
  246. ; 1x0
  247.     move            y:<zsample,a
  248.     neg    a
  249.  
  250. ; filter (with integrator) those zero crossings
  251. ssi_r3    move    a,x0
  252.     mpyr    x0,x1,a     x:<rwalk,x0
  253.     add    x0,a        #0.05,x0
  254.     move            a,x:<rwalk
  255.  
  256. ; check if timing error too big (and advance/retard timing if necessary)
  257.     cmpm    x0,a        #retard,b1
  258.     jlo    <ssi_r4
  259.     tst    a        #advance,a1         ; threshold exceeded, adjust timing
  260.     tmi    b,a
  261.     move            a1,x:<adccmd
  262.     move            #adjlen,a1
  263.     clr    b        a1,x:<adcnt
  264.     move            b1,x:<rwalk
  265.  
  266. ; unscramble symbol, result in C
  267. ssi_r4    btst    #0,x:<samque
  268.     move            x:<usrem,b1
  269.     jcc    <unscram
  270.     move            #>(poly<<1)|1,x0
  271.     eor    x0,b
  272. unscram lsr    b
  273.     move            b1,x:<usrem
  274.  
  275. ; make symbol decision (with NRZ-S decoding), databit in C, result in C
  276.     rol    b        x:<prvrsym,x0
  277.     eor    x0,b        b1,x:<prvrsym
  278.     not    b
  279.     lsr    b
  280.  
  281. ; forward to the HDLC handler
  282.     jsr    <putbit
  283.  
  284. ssi_end jmp    <rec
  285.  
  286.  
  287. ;****************************
  288. ;*     Transmitter        *
  289. ;****************************
  290. ; check if we can calculate new samples
  291. xmit    move            r3,a
  292.     move            r7,x0
  293.     cmp    x0,a
  294.     jeq    <loop
  295.  
  296. ; yes, check if the transmitter is on at all
  297.     clr    a
  298.     jclr    #ptt,x:<status,xmt2
  299.  
  300. ; xmit mode, check if we need a new symbol
  301.     bchg    #toggle,x:<status
  302.     jcc    <xmt1
  303.  
  304. ; yes, check on what phase we are
  305.     jset    #xmt,x:<status,xmt0
  306.  
  307. ; training phase, send continuous preamble (zero pattern)
  308.     andi    #$fe,ccr
  309.     jmp    <morebit
  310.  
  311. ; data phase, get a new bit to xmit
  312. xmt0    jsr    <getbit
  313.     jne    <morebit
  314. ; there is no more bits to send, switch to receiving mode
  315.     jsr    <shutx
  316.     andi    #$fc,mr
  317.  
  318. ; NRZ-S coding
  319. morebit rol    a        x:<prvxsym,x0
  320.     not    a
  321.     eor    x0,a        #-1.0,x0
  322.     ror    a        a1,x:<prvxsym
  323.  
  324. ; scrambler, databit in C flag, result in a (-1 or 1)
  325.     clr    a
  326.     rol    a        x:<srem,x0
  327.     eor    x0,a        #-0.9,x1
  328.     lsr    a        #>poly,x0
  329.     jcc    <scram
  330.     eor    x0,a
  331. scram    move            a1,x:<srem
  332.     move            #0.9,a
  333.     tcc    x1,a
  334.  
  335. ; squared raised cosine shape output filter
  336. xmt1    move            x:<outfptr,r4
  337.     move            #<xcos,r0
  338.     move            #<N-1,m4
  339.     move            a,x:(r4)
  340.     conv    1,N,r4,r0,a
  341.     move            r4,x:<outfptr
  342.     move            #-1,m4
  343.  
  344. ; send a new bit
  345.     move            a,x0            ; adjust output level
  346.     move            x:<gain,x1
  347.     mpyr    x0,x1,a     #>$fffc<<8,x0
  348. xmt2    and    x0,a        x:<adcnt,b
  349.     tst    b        #>1,y0            ; check if we must adjust timing
  350.     jeq    <xmt3
  351.     sub    y0,b        x:<adccmd,x0        ; yes, add converter chip control cmds
  352.     or    x0,a        b1,x:<adcnt
  353. xmt3    move            a,x:(r7)+
  354.  
  355. scx_end jmp    <xmit
  356.  
  357.  
  358. ;****************************
  359. ;*     DATA - AREA        *
  360. ;****************************
  361.  
  362.     org    x:
  363.  
  364. adccmd    ds    1                    ; ADC timing command
  365. adcnt    ds    1                    ; ADC timing command counter
  366. samque    ds    1                    ; received sample queue
  367. prvrsym ds    1                    ; previous received symbol
  368. prvxsym ds    1                    ; previous xmitted symbol
  369. rwalk    ds    1                    ; random walk filter counter
  370. rds    ds    2                    ; desicion sample filter
  371. rzs    ds    2                    ; zero sample filter
  372. rdc    ds    2                    ; DC-level filter
  373. anacnt    ds    1                    ; signal quality analyzing lenght counter
  374. usrem    ds    1
  375. srem    ds    1
  376. outfptr ds    1                    ; output filter pointer
  377. agcgain ds    1                    ; current DAGC gain
  378.  
  379. tmp    ds    1
  380.  
  381.     org    y:
  382.  
  383. zsample ds    1                    ; current zero crossing sample
  384. dsample ds    1                    ; previous decision sample
  385.  
  386.     endsec
  387.  
  388.  
  389. ;****************************
  390. ;*    M*BITS MODULO DATA    *
  391. ;****************************
  392.     section PAMData
  393.     xdef    N,inN,outN,rcos,xcos
  394.     xdef    insamp,outsamp,outfilt
  395.  
  396.     org    x:
  397.  
  398. ; PAM demod parameters
  399. N    equ    13                    ; samples per filter
  400. inN    equ    16                    ; input buffer lenght
  401. outN    equ    8                    ; output buffer lenght
  402.  
  403. insamp    ds    inN
  404. outfilt ds    N
  405.     ds    16-N
  406. outsamp ds    8
  407.  
  408.     org    y:
  409.  
  410. ; receiver filter
  411. ; square root of raised cosine pulse filter constants
  412. ; beta = 6/16 = 0.375
  413. rcos    dc    -0.0082167989
  414.     dc     0.0071048900
  415.     dc     0.0254175599
  416.     dc    -0.0592829199
  417.     dc    -0.0434475299
  418.     dc     0.2999202999
  419.     dc     0.5512325000
  420.     dc     0.2999202999
  421.     dc    -0.0434475299
  422.     dc    -0.0592829199
  423.     dc     0.0254175599
  424.     dc     0.0071048900
  425.     dc    -0.0082167989
  426.  
  427. ; transmit filter
  428. ; square root of raised cosine pulse filter constants
  429. ; beta = 6/16 = 0.375
  430. xcos    dc    -0.0082167989
  431.     dc     0.0071048900
  432.     dc     0.0254175599
  433.     dc    -0.0592829199
  434.     dc    -0.0434475299
  435.     dc     0.2999202999
  436.     dc     0.5512325000
  437.     dc     0.2999202999
  438.     dc    -0.0434475299
  439.     dc    -0.0592829199
  440.     dc     0.0254175599
  441.     dc     0.0071048900
  442.     dc    -0.0082167989
  443.  
  444.     endsec
  445.  
  446.     end
  447.